package com.bank.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bank.dto.Result;
import com.bank.entity.TradeInfo;
import com.bank.service.CardInfoService;
import com.bank.service.TradeInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 客户控制器
 * 处理客户相关的所有功能请求
 * 
 * @author 开发团队
 * @version 1.0.0
 * @since 2025-06-19
 */
@Slf4j
@Controller
@RequestMapping("/customer")
@Validated
public class CustomerController {

    @Autowired
    private CardInfoService cardInfoService;

    @Autowired
    private TradeInfoService tradeInfoService;

    /**
     * 客户首页
     * 
     * @param model 模型
     * @return 客户首页视图
     */
    @GetMapping({"", "/", "/index"})
    public String index(Model model) {
        return "customer/index";
    }

    // ================================
    // 余额查询、交易查询（5分）
    // ================================

    /**
     * 余额查询页面
     * 
     * @param model 模型
     * @return 余额查询视图
     */
    @GetMapping("/balance")
    public String balance(Model model) {
        return "customer/balance";
    }

    /**
     * 查询银行卡余额
     * 
     * @param cardId 卡号
     * @param password 密码
     * @return 余额信息
     */
    @PostMapping("/balance/query")
    @ResponseBody
    public Result<BigDecimal> queryBalance(
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotBlank(message = "密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "密码格式不正确，应为6位数字") String password) {
        
        return cardInfoService.getBalance(cardId, password);
    }

    /**
     * 交易查询页面
     * 
     * @param model 模型
     * @return 交易查询视图
     */
    @GetMapping("/trades")
    public String trades(Model model) {
        return "customer/trades";
    }

    /**
     * 分页查询交易记录（客户使用）
     * 
     * @param current 当前页
     * @param size 页大小
     * @param cardId 卡号
     * @param password 密码
     * @param tradeType 交易类型（可选）
     * @param startTime 交易开始时间（可选）
     * @param endTime 交易结束时间（可选）
     * @return 分页结果
     */
    @PostMapping("/trades/page")
    @ResponseBody
    public Result<IPage<TradeInfo>> getTradesPage(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size,
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotBlank(message = "密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "密码格式不正确，应为6位数字") String password,
            @RequestParam(required = false) String tradeType,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm") LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm") LocalDateTime endTime) {
        
        Page<TradeInfo> page = new Page<>(current, size);
        return tradeInfoService.getTradesPageByCardId(page, cardId, password, tradeType, startTime, endTime);
    }

    // ================================
    // 存款、取款（5分）
    // ================================

    /**
     * 存取款页面
     * 
     * @param model 模型
     * @return 存取款视图
     */
    @GetMapping("/deposit-withdraw")
    public String depositWithdraw(Model model) {
        return "customer/deposit-withdraw";
    }

    /**
     * 存款操作
     * 
     * @param cardId 卡号
     * @param amount 存款金额
     * @param remark 备注
     * @return 操作结果
     */
    @PostMapping("/deposit")
    @ResponseBody
    public Result<BigDecimal> deposit(
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotNull(message = "存款金额不能为空") 
            @DecimalMin(value = "0.01", message = "存款金额必须大于0") BigDecimal amount,
            @RequestParam(required = false) String remark) {
        
        return cardInfoService.deposit(cardId, amount, remark);
    }

    /**
     * 取款操作
     * 
     * @param cardId 卡号
     * @param password 密码
     * @param amount 取款金额
     * @param remark 备注
     * @return 操作结果
     */
    @PostMapping("/withdraw")
    @ResponseBody
    public Result<BigDecimal> withdraw(
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotBlank(message = "密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "密码格式不正确，应为6位数字") String password,
            @RequestParam @NotNull(message = "取款金额不能为空") 
            @DecimalMin(value = "0.01", message = "取款金额必须大于0") BigDecimal amount,
            @RequestParam(required = false) String remark) {
        
        return cardInfoService.withdraw(cardId, password, amount, remark);
    }

    // ================================
    // 挂失、修改密码（5分）
    // ================================

    /**
     * 账户管理页面
     * 
     * @param model 模型
     * @return 账户管理视图
     */
    @GetMapping("/account")
    public String account(Model model) {
        return "customer/account";
    }

    /**
     * 银行卡挂失
     * 
     * @param cardId 卡号
     * @param password 密码
     * @return 操作结果
     */
    @PostMapping("/report-loss")
    @ResponseBody
    public Result<String> reportLoss(
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotBlank(message = "密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "密码格式不正确，应为6位数字") String password) {
        
        return cardInfoService.reportLoss(cardId, password);
    }

    /**
     * 银行卡解挂
     * 
     * @param cardId 卡号
     * @param password 密码
     * @return 操作结果
     */
    @PostMapping("/cancel-report-loss")
    @ResponseBody
    public Result<String> cancelReportLoss(
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotBlank(message = "密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "密码格式不正确，应为6位数字") String password) {
        
        return cardInfoService.cancelReportLoss(cardId, password);
    }

    /**
     * 修改银行卡密码
     * 
     * @param cardId 卡号
     * @param oldPassword 原密码
     * @param newPassword 新密码
     * @return 操作结果
     */
    @PostMapping("/change-password")
    @ResponseBody
    public Result<String> changePassword(
            @RequestParam @NotBlank(message = "银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "银行卡号格式不正确，应为16位数字") String cardId,
            @RequestParam @NotBlank(message = "原密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "原密码格式不正确，应为6位数字") String oldPassword,
            @RequestParam @NotBlank(message = "新密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "新密码格式不正确，应为6位数字") String newPassword) {
        
        return cardInfoService.changePassword(cardId, oldPassword, newPassword);
    }

    // ================================
    // 转账功能（高级功能）
    // ================================

    /**
     * 转账页面
     * 
     * @param model 模型
     * @return 转账视图
     */
    @GetMapping("/transfer")
    public String transfer(Model model) {
        return "customer/transfer";
    }

    /**
     * 转账操作
     * 
     * @param fromCardId 转出卡号
     * @param fromPassword 转出卡密码
     * @param toCardId 转入卡号
     * @param amount 转账金额
     * @param remark 备注
     * @return 操作结果
     */
    @PostMapping("/transfer")
    @ResponseBody
    public Result<String> transfer(
            @RequestParam @NotBlank(message = "转出银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "转出银行卡号格式不正确，应为16位数字") String fromCardId,
            @RequestParam @NotBlank(message = "转出银行卡密码不能为空") 
            @Pattern(regexp = "^[0-9]{6}$", message = "转出银行卡密码格式不正确，应为6位数字") String fromPassword,
            @RequestParam @NotBlank(message = "转入银行卡号不能为空") 
            @Pattern(regexp = "^[0-9]{16}$", message = "转入银行卡号格式不正确，应为16位数字") String toCardId,
            @RequestParam @NotNull(message = "转账金额不能为空") 
            @DecimalMin(value = "0.01", message = "转账金额必须大于0") BigDecimal amount,
            @RequestParam(required = false) String remark) {
        
        return tradeInfoService.transfer(fromCardId, fromPassword, toCardId, amount, remark);
    }
}
